package com.hjx.datareporter;

import cn.hutool.json.JSONObject;
import com.hjx.objectassert.model.BillAllData;
import com.hjx.objectassert.model.CreditCardAllData;
import com.hjx.objectassert.model.Expense;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.function.Function;
import java.util.stream.Stream;

public class Reporter<T> implements Callable<T> {

    private CreditCardAllData cardAllData;
    private ExecutorService pool;

    public Reporter(CreditCardAllData cardAllData, ExecutorService pool){
        this.cardAllData = cardAllData;
        this.pool = pool;
    }

    @Override
    public T call() {
        JSONObject report = initReportCommonPart();
        if("信用卡".equals(cardAllData.getCardType())){
            report.put("creditCardReport", initCreditCardReport());
            calculatorCreditUserBasicInfo(report, cardAllData);
        } else {
            report.put("debitCardReport", initDebitCardReport());
            calculatorDebitUserBasicInfo(report, cardAllData);
        }

//        System.out.println(cardAllData.getBalance());
        return (T) report;
    }

    private void calculatorDebitUserBasicInfo(JSONObject report, CreditCardAllData creditCardAllData) {
        JSONObject userBasicInfo = getDebitJSONObject(report, "user_basic_info");
//        姓名
        userBasicInfo.put("name", creditCardAllData.getNameOnCard());
//        性别
        userBasicInfo.put("gender", "");
//        证件类型
        userBasicInfo.put("certify_type", "");
//        证件号码
        userBasicInfo.put("certify_no", "");
//        手机号
        userBasicInfo.put("mobile", "");
//        家庭地址
        userBasicInfo.put("address", "");
//        邮箱
        userBasicInfo.put("email", "");
//        活跃银行卡数
        userBasicInfo.put("active_card_num", 1);
//        活跃银行数
        userBasicInfo.put("bank_num", 1);
//        当前工作单位名称
        userBasicInfo.put("last_company_name", "");
//        近1年工作单位数量
        userBasicInfo.put("company_num_1y", "");
//        近1年收入（元）
        userBasicInfo.put("income_amt_1y",
//                        流化
                creditCardAllData.getBills().stream().parallel()
//                        过滤账单为空的月份
                        .filter(billAllData -> billAllData != null && billAllData.getShoppingSheets().size() > 0)
                        .filter(this::timeFilter)
//                        取账单中的记录
                        .map(BillAllData::getShoppingSheets)
//                        合并所有账单记录到一个Stream
                        .flatMap((Function<List<Expense>, Stream<Expense>>) Collection::stream)
//                        过滤非工资类型账单记录
                        .filter(expense -> expense.getAmountMoney().compareTo(BigDecimal.ZERO) < 0)
//                        取消费金额
                        .map(Expense::getAmountMoney)
//                        累加所有消费金额
                        .reduce(BigDecimal::add)
//                        取正值
                        .map(BigDecimal::negate)
//                        若累加结果不存在取0
                        .orElse(BigDecimal.ZERO)
                        .toString());

//        近1年工资收入（元）
        userBasicInfo.put("salary_income_1y",
//                        流化
                creditCardAllData.getBills().stream().parallel()
//                        过滤账单为空的月份
                        .filter(billAllData -> billAllData != null && billAllData.getShoppingSheets().size() > 0)
                        .filter(this::timeFilter)
//                        取账单中的记录
                        .map(BillAllData::getShoppingSheets)
//                        合并所有账单记录到一个Stream
                        .flatMap(new Function<List<Expense>, Stream<Expense>>() {
                            @Override
                            public Stream<Expense> apply(List<Expense> expenses) {
                                return expenses.stream();
                            }
                        })
//                        过滤非工资类型账单记录
                        .filter(expense -> expense.getCategory().equals("SALARY"))
//                        取消费金额
                        .map(Expense::getAmountMoney)
//                        累加所有消费金额
                        .reduce(BigDecimal::add)
//                        取正值
                        .map(BigDecimal::negate)
//                        若累加结果不存在取0
                        .orElse(BigDecimal.ZERO)
                        .toString());
//        近1年贷款收入（元）
        userBasicInfo.put("loan_in_1y", "");
//        近1年支出（元）
        userBasicInfo.put("expense_1y", "");
//        近1年消费支出（元）
        userBasicInfo.put("consumption_expense_1y", "");
//        近1年还贷支出（元）
        userBasicInfo.put("loan_out_1y", "");
    }

    private boolean timeFilter(BillAllData billAllData) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        LocalDate billMonthLocalDate = LocalDate.parse(sdf.format(billAllData.getBillDate()), df);
        return LocalDate.now().minusYears(1).isBefore(billMonthLocalDate);
    }

    private void calculatorCreditUserBasicInfo(JSONObject report, CreditCardAllData creditCardAllData) {
        JSONObject userBasicInfo = getCreditJSONObject(report, "user_basic_info");
//        姓名
        userBasicInfo.put("name", creditCardAllData.getNameOnCard());
//        性别
        userBasicInfo.put("gender", "");
//        证件类型
        userBasicInfo.put("certify_type", "");
//        证件号码
        userBasicInfo.put("certify_no", "");
//        手机号
        userBasicInfo.put("mobile", "");
//        家庭地址
        userBasicInfo.put("address", "");
//        邮箱
        userBasicInfo.put("email", "");
//        活跃银行卡数
        userBasicInfo.put("active_card_num", 1);
//        活跃银行数
        userBasicInfo.put("bank_num", 1);
//        当前工作单位名称
        userBasicInfo.put("last_company_name", "");
//        近1年工作单位数量
        userBasicInfo.put("company_num_1y", "");
//        近1年收入（元）
        userBasicInfo.put("income_amt_1y", "");
//        近1年工资收入（元）
        userBasicInfo.put("salary_income_1y", "");
//        近1年贷款收入（元）
        userBasicInfo.put("loan_in_1y", "");
//        近1年支出（元）
        userBasicInfo.put("expense_1y", "");
//        近1年消费支出（元）
        userBasicInfo.put("consumption_expense_1y", "");
//        近1年还贷支出（元）
        userBasicInfo.put("loan_out_1y", "");
    }

    private JSONObject initReportCommonPart() {
        JSONObject commonPart = new JSONObject();
        commonPart.put("code", "200");
        commonPart.put("message", "成功");
        commonPart.put("update_time", new Date());
        return commonPart;
    }

    private JSONObject getCreditJSONObject(JSONObject report, String key){
        return (JSONObject) ((JSONObject) report.get("creditCardReport")).get(key);
    }

    private JSONObject getDebitJSONObject(JSONObject report, String key){
        return (JSONObject) ((JSONObject) report.get("debitCardReport")).get(key);
    }

    private JSONObject initDebitCardReport() {
        JSONObject debitCardReport = new JSONObject();
        debitCardReport.put("user_basic_info", new JSONObject());
        debitCardReport.put("account_summary", new JSONObject());
        debitCardReport.put("debitcard_summary",new JSONObject());
        debitCardReport.put("debitcard_detailses",new JSONObject());
        debitCardReport.put("debitcard_undue_regular_basis_list",new JSONObject());
        debitCardReport.put("work_details_list",new JSONObject());
        return debitCardReport;
    }

    private JSONObject initCreditCardReport() {
        JSONObject creditCardReport = new JSONObject();
        creditCardReport.put("user_basic_info", new JSONObject());
        creditCardReport.put("account_summary", new JSONObject());
        creditCardReport.put("credit_card_summary",new JSONObject());
        creditCardReport.put("repayment_summary",new JSONObject());
        creditCardReport.put("overdue_information",new JSONObject());
        creditCardReport.put("interest_information",new JSONObject());
        creditCardReport.put("sales_amount",new JSONObject());
        creditCardReport.put("balance", new JSONObject());
        creditCardReport.put("repayment", new JSONObject());
        creditCardReport.put("quota", new JSONObject());
        creditCardReport.put("interest", new JSONObject());
        creditCardReport.put("income", new JSONObject());
        creditCardReport.put("overrun", new JSONObject());
        creditCardReport.put("overdue_creditcard", new JSONObject());
        creditCardReport.put("other_attribute", new JSONObject());
        return creditCardReport;
    }
}
